import router from '@/routers/index';
import { usePermissionStore } from '@/store/modules/permission';
import { useUserStore } from '@/store/modules/user';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
import { RouteRecordRaw } from 'vue-router';

NProgress.configure({ showSpinner: false }); // NProgress Configuration

// 白名单路由
const whiteList = ['/login'];

// 第三方登录回调路由检查
const checkThirdPartyCallback = (to: any): boolean => {
  const callbacks = ['QQCallback', 'GithubCallback'];
  return callbacks.includes(to.name) || (to.query?.code && to.query?.state);
};

/**
 * 路由守卫：检查并生成动态路由
 */
router.beforeEach(async (to, from, next) => {
  // 开启进度条和设置标题
  NProgress.start();
  document.title = typeof to.meta.title === 'string' ? to.meta.title : 'MonkeyK';

  const UserStore = useUserStore();
  const PermissionStore = usePermissionStore();
  const hasToken = UserStore.token;
  const currentSignature = UserStore.routeSignature;

  // 第三方登录回调直接通过
  if (checkThirdPartyCallback(to)) {
    console.log('第三方登录回调:', { path: to.path, name: to.name });
    next();
    return;
  }

  // 已登录用户的路由处理
  if (hasToken) {
    await handleAuthenticatedUser(to, next, UserStore, PermissionStore, currentSignature);
    return;
  }

  // 游客用户的路由处理
  await handleGuestUser(to, next, UserStore, PermissionStore, currentSignature);
});

/**
 * 处理已登录用户的路由逻辑
 */
async function handleAuthenticatedUser(
  to: any,
  next: Function,
  UserStore: any,
  PermissionStore: any,
  currentSignature: string
) {
  // 登录页重定向到首页
  if (to.path === '/login') {
    next({ path: '/' });
    return;
  }

  try {
    const shouldRebuild = checkIfNeedRebuild(to, PermissionStore, currentSignature, true);

    if (shouldRebuild.need) {
      console.log('已登录用户路由重建:', shouldRebuild.reason);
      await rebuildRoutes(UserStore.roles, PermissionStore, currentSignature);
      next({ ...to, replace: true });
    } else {
      console.log('已登录用户正常跳转:', { path: to.path, name: to.name });
      next();
    }
  } catch (error) {
    console.error('已登录用户路由处理失败:', error);
    await UserStore.resetToken();
    next(`/login?redirect=${to.path}`);
  }
}

/**
 * 处理游客用户的路由逻辑
 */
async function handleGuestUser(
  to: any,
  next: Function,
  UserStore: any,
  PermissionStore: any,
  currentSignature: string
) {
  // 白名单直接通过
  if (whiteList.includes(to.path)) {
    next();
    return;
  }

  // 设置游客权限并处理路由
  await UserStore.loginByGuest();

  const shouldRebuild = checkIfNeedRebuild(to, PermissionStore, currentSignature, false);

  if (shouldRebuild.need) {
    console.log('游客路由重建:', shouldRebuild.reason);
    await rebuildRoutes(UserStore.roles, PermissionStore, currentSignature);
    next({ ...to, replace: true });
  } else {
    console.log('游客正常跳转:', { path: to.path, name: to.name });
    next();
  }
}

/**
 * 检查是否需要重建路由
 */
function checkIfNeedRebuild(
  to: any,
  PermissionStore: any,
  currentSignature: string,
  isAuthenticated: boolean
): { need: boolean; reason: any } {
  const routeNotFound = to.matched.length === 0;
  const targetRouteExists =
    router.hasRoute(to.name as string) || router.getRoutes().some(route => route.path === to.path);

  // 检查是否有持久化的路由数据但实际路由已被清空
  const hasPersistedRoutes = PermissionStore.checkAndFixRoutes();
  const actualRouteCount = router.getRoutes().length;
  const constantRouteCount = 3; // 常量路由大约数量（layout、login、404等）
  const hasLostRoutes = hasPersistedRoutes && actualRouteCount <= constantRouteCount;

  const hasValidSignature = currentSignature && currentSignature !== 'empty-roles';
  const signatureChanged = PermissionStore.appliedSignature !== currentSignature;

  // 页面刷新后需要重建路由的条件：
  // 1. 签名发生变化
  // 2. 有持久化路由但实际路由丢失（页面刷新情况）
  // 3. 找不到路由且不是首次访问
  const shouldRebuild =
    signatureChanged ||
    (hasLostRoutes && isAuthenticated) ||
    (routeNotFound && !targetRouteExists && hasValidSignature);

  return {
    need: shouldRebuild,
    reason: {
      signatureChanged,
      routeNotFound,
      targetRouteExists,
      hasPersistedRoutes,
      hasLostRoutes,
      actualRouteCount,
      hasValidSignature,
      appliedSignature: PermissionStore.appliedSignature,
      currentSignature,
      toPath: to.path,
      toName: to.name
    }
  };
}

/**
 * 重建路由
 */
async function rebuildRoutes(
  roles: string[],
  PermissionStore: any,
  currentSignature: string
): Promise<void> {
  try {
    // 清空现有的动态路由
    PermissionStore.clearRoutes();

    // 生成新的路由
    const accessRoutes = await PermissionStore.generateRoutes(roles);

    // 重新添加路由到 router 实例
    accessRoutes.forEach((item: RouteRecordRaw) => {
      try {
        router.addRoute(item);
      } catch (error) {
        console.warn('添加路由失败:', item.name, error);
      }
    });

    // 设置已应用签名
    PermissionStore.setAppliedSignature(currentSignature);

    console.log('路由重建完成:', {
      角色权限: roles,
      动态路由数量: accessRoutes.length,
      总路由数量: router.getRoutes().length,
      签名: currentSignature
    });
  } catch (error) {
    console.error('路由重建过程中发生错误:', error);
    throw error;
  }
}

router.afterEach(() => {
  NProgress.done();
});
